package crmdna.client.user;

import java.util.List;
import java.util.Set;

import crmdna.client.group.Group;
import crmdna.client.user.UserCore.UserProp;
import crmdna.common.APIException;
import crmdna.common.APIResponse.Status;
import crmdna.common.Utils;
import crmdna.crmdna.Client;

public class User {
	
	public enum ResourceType {
		GROUP, USER, INTERACTION, PRACTICE, PROGRAM_TYPE, VENUE, TEACHER, PROGRAM,
		CUSTOM_CONFIG
	}
	
	public enum Action {
		READ, WRITE
	}
	
	public static final String SUPER_USER = "sathyanarayanant@gmail.com";
		
	
	public static UserProp create(String client, String email, long groupId, String login) {
		Client.ensureValidClient(client);		
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		Group.safeGet(client, groupId);
		
		return UserCore.create(client, email, groupId);				
	}
	
	public static UserProp updateEmail(String client, String existingEmail, 
			String newEmail, String login) {
		
		Client.ensureValidClient(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		
		UserProp userProp = UserCore.updateEmail(client, existingEmail, newEmail);
		return userProp;					
	}
	
	public static UserProp updateGroup(String client, String email, 
			long newGroupId, String login) {
		
		Client.ensureValidClient(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		Group.safeGet(client, newGroupId);
		
		return UserCore.updateGroup(client, email, newGroupId);								
	}	
	
	public static UserEntity get(String client, String email) {
		
		Client.ensureValidClient(client);
		return UserCore.get(client, email);		
	}
	
	public static UserEntity safeGet(String client, String email) {
		
		Client.ensureValidClient(client);
		return UserCore.safeGet(client, email);	
	}
	
	public static List<UserProp> getAll(String client) {
		
		Client.ensureValidClient(client);		
		return UserCore.getAll(client);		
	}
	
	public static List<UserProp> getAllForGroup(String client, long groupId) {
		Client.ensureValidClient(client);		
		return UserCore.getAllForGroup(client, groupId);		
	}
	
	public static UserProp addOrDeletePrivilege(String client, String email, ResourceType resourceType, 
			long resourceId, Action action, boolean add, String login) {
		
		Client.ensureValidClient(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		
		UserProp userProp = UserCore.addOrDeletePrivilege(client, email, 
				resourceType.toString(), resourceId, action.toString(), add);						
		return userProp;
	}
	
	public static UserProp clonePrivileges(String client, String sourceEmail, 
			String targetEmail, String login) {		
		
		Client.ensureValidClient(client);
		ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
							
		UserProp userProp = UserCore.clonePrivileges(client, sourceEmail, targetEmail);		
		return userProp;			
	}
	
	public static void ensureValidUser(String client, String login) {
		
		Client.ensureValidClient(client);
		UserCore.ensureValidUser(client, login);		
	}
		
	public static void ensureAccess(String client, String login, ResourceType resourceType, 
			long resourceId, Action action) {	
		
		Client.ensureValidClient(client);
						
		if ((null == login) || login.equals(""))
			throw new APIException(Status.ERROR_LOGIN_REQUIRED, "Email cannot be null or empty");
		
		if (null == resourceType)
			Utils.throwIncorrectSpecException("resourceType cannot be null");
		
		if (null == action)
			Utils.throwIncorrectSpecException("action cannot be null");
		
		UserCore.ensureAccess(client, login, resourceType.toString(), resourceId, action.toString());		
	}	
	
	public static Set<Long> getResources(String client, String login, ResourceType resourceType, 
			Action action) {
		
		Client.ensureValidClient(client);
		
		if (null == resourceType)
			Utils.throwIncorrectSpecException("resourceType cannot be null");
		
		if (null == action)
			Utils.throwIncorrectSpecException("action cannot be null");
		
		return UserCore.getResources(client, login, resourceType.toString(), action.toString());
		
	}
}